﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
using CheckLift.Common.Impl;
using CheckLift.Common.ViewConfigImpl;
using System.Configuration;
using CheckLift.Common.Intf;
using System.Collections;
using DataGridFilterLibrary;

namespace CheckLift.UI.Controls
{
    /// <summary>
    /// Interaction logic for DataGridFilterCtrlEx.xaml
    /// </summary>
    public partial class DataGridFilterCtrlEx : UserControl, INotifyPropertyChanged
    {

        public OnDataGridSelectedDataEvent OnDataGridSelectedData;

        public DataGridFilterCtrlEx()
        {
            InitializeComponent();

            CommandBindings.Add(new CommandBinding(
                Commands.SelectFirst,
                (sender, e) => SelectFirstItem(),
                (sender, e) => e.CanExecute = CanSelectFirstItem()
                ));

            CommandBindings.Add(new CommandBinding(
                Commands.SelectLast,
                (sender, e) => SelectLastItem(),
                (sender, e) => e.CanExecute = CanSelectLastItem()
                ));

            CommandBindings.Add(new CommandBinding(
                Commands.SelectNext,
                (sender, e) => SelectNextItem(),
                (sender, e) => e.CanExecute = CanSelectNextItem()
                ));

            CommandBindings.Add(new CommandBinding(
                Commands.SelectPrevious,
                (sender, e) => SelectPreviousItem(),
                (sender, e) => e.CanExecute = CanSelectPreviousItem()
                ));
        }

        public SearchReportType SearchReportTypeEnum { get; set; }

        private class SearchObj
        {
            public String DisplayName { get; set; }
            public String FieldName { get; set; }
            //public Type Type { get; set; }
        }

        private void PrepareMetaData()
        {
            if (ReportsView.CurrentItem == null)
                return;
            List<SearchObj> lst = new List<SearchObj>();

            Type T = ReportsView.CurrentItem.GetType();

            UpdateColumn(lst, T);

            //if (lst.Count > 0)
            //{
            //    cbFindBy.ItemsSource = lst;
            //    cbFindBy.DisplayMemberPath = "DisplayName";
            //    cbFindBy.SelectedValue = "FieldName";
            //    cbFindBy.SelectedIndex = 0;
            //}
            //else
            //    dpFilterBy.Visibility = System.Windows.Visibility.Collapsed;
        }

        private void UpdateColumn(List<SearchObj> lst, Type T)
        {
            ViewConfigurationSection viewConfig = ConfigurationManager.GetSection("ViewConfiguration") as ViewConfigurationSection;
            GridViewElement gridViewElem = viewConfig.GridViewConfigurations[T.Name];
            if (gridViewElem == null)
                return;

            foreach (ColumnViewElement item in gridViewElem.ColumnViews)
            {
                DataGridBoundColumn col;
                if (String.IsNullOrEmpty(item.ColumnType) || item.ColumnType.Equals("String"))
                {
                    col = new DataGridTextColumn();
                }
                else
                {
                    col = new DataGridCheckBoxColumn();
                }

                col.Binding = new Binding(item.BindToField);
                col.Header = item.TranslateKey;
                col.Visibility = item.IsVisible ? System.Windows.Visibility.Visible : System.Windows.Visibility.Hidden;
                if (item.IsVisible)
                {

                    if (item.IsFilterField)
                    {
                        if (lst.Count > item.FilterOrder)
                            lst.Insert(item.FilterOrder, new SearchObj() { DisplayName = item.TranslateKey, FieldName = item.BindToField });
                        else
                            lst.Add(new SearchObj() { DisplayName = item.TranslateKey, FieldName = item.BindToField });
                    }
                    else
                    {
                        col.SetValue(DataGridColumnExtensions.DoNotGenerateFilterControlProperty, true);
                    }
                }

                dgItemsEx.Columns.Add(col);
            }
        }

        public Guid MainFilterParamGUID
        {
            get
            {
                return (Guid)GetValue(MainFilterParamGUIDProperty);
            }
            set
            {
                SetValue(MainFilterParamGUIDProperty, value);
                if (ReportsView != null)
                {
                    ReportsView.Filter = ReportsFilter;
                    OnPropertyChanged("TotalReports");
                }
            }
        }

        public bool ReportsFilter(object item)
        {
            SearchReportType searchReportType;
            if (Enum.TryParse<SearchReportType>(GetValue(SearchReportTypeProperty).ToString(), out searchReportType))
            {
                switch (searchReportType)
                {
                    case SearchReportType.CustomSearch:
                        return false;
                    case SearchReportType.SearchByCompany:
                        return ((IReport)item).Lift.Customer.CompanyId.Equals(MainFilterParamGUID);
                    case SearchReportType.SearchByService:
                        return ((IReport)item).Lift.ServiceId.Equals(MainFilterParamGUID);
                    default:
                        break;
                }
            }
            return false;
        }

        private void CheckOrCreateReportsView()
        {
            if (ReportsView == null)
            {
                ReportsView = CollectionViewSource.GetDefaultView(GetValue(ItemsDataProperty));
                if (ReportsView != null)
                {
                    ReportsView.CurrentChanged += new EventHandler(ReportsView_CurrentChanged);
                    PrepareMetaData();
                    dgItemsEx.ItemsSource = ReportsView;
                    OnPropertyChanged("CurrentReportIndex");
                }
            }
        }

        void ReportsView_CurrentChanged(object sender, EventArgs e)
        {
            OnPropertyChanged("CurrentReportIndex");
        }

        public static readonly DependencyProperty SearchReportTypeProperty = DependencyProperty.Register("SearchReportTypeEnum", typeof(SearchReportType), typeof(DataGridFilterCtrlEx));
        public static readonly DependencyProperty MainFilterParamGUIDProperty = DependencyProperty.Register("MainFilterParamGUID", typeof(Guid), typeof(DataGridFilterCtrlEx));
        //public static readonly DependencyProperty MainFilterParamIntProperty = DependencyProperty.Register("MainFilterParamInt", typeof(int), typeof(DataGridFilterCtrlEx));
        public static DependencyProperty ItemsDataProperty = DependencyProperty.Register("ItemsData", typeof(IEnumerable), typeof(DataGridFilterCtrlEx),
            new FrameworkPropertyMetadata(null,
                       OnItemsDataPropertyChanged));
        public static readonly DependencyProperty OnDataGridSelectedDataEventProp = DependencyProperty.Register("OnDataGridSelectedDataEvent", typeof(OnDataGridSelectedDataEvent), typeof(DataGridFilterCtrlEx));

        public IEnumerable ItemsData
        {
            get
            {
                return (IEnumerable)GetValue(ItemsDataProperty);
            }
            set
            {
                SetValue(ItemsDataProperty, value);
                CheckOrCreateReportsView();
                OnPropertyChanged("TotalReports");
            }
        }


        private static void OnItemsDataPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
        {
            (source as DataGridFilterCtrlEx).ItemsData = e.NewValue as IEnumerable;
        }


        ICollectionView ReportsView;

        #region Selection Navigation Code
        //The code for the Navigation may look like an overhead in the ViewModel but keep in mind that in a real life application you will be doing validation and what not inside here!

        public bool CanSelectFirstItem()
        {
            return ReportsView == null ? false : ReportsView.CurrentPosition > 0;
        }

        public void SelectFirstItem()
        {
            if (ReportsView != null)
                ReportsView.MoveCurrentToFirst();
        }

        public int TotalReports
        {
            get
            {
                return ReportsView == null ? 0 : ((ListCollectionView)ReportsView).Count;
            }
        }

        public int CurrentReportIndex
        {
            get
            {

                return ReportsView == null ? 0 : ReportsView.CurrentPosition + 1;
            }
        }

        public bool CanSelectLastItem()
        {
            //Please note that this is done in such a way and not in myData.Count because if there is filtering being applied we need to make sure that the count of items is correct!            
            return ReportsView == null ? false : ReportsView.CurrentPosition < ReportsView.Cast<object>().Count() - 1;
        }

        public void SelectLastItem()
        {
            if (ReportsView != null)
                ReportsView.MoveCurrentToLast();
        }

        public bool CanSelectNextItem()
        {
            return CanSelectLastItem();
        }

        public void SelectNextItem()
        {
            ReportsView.MoveCurrentToNext();
        }

        public bool CanSelectPreviousItem()
        {
            return CanSelectFirstItem();
        }

        public void SelectPreviousItem()
        {
            ReportsView.MoveCurrentToPrevious();
        }

        #endregion

        #region Properties used for Filtering
        string searchText = String.Empty;
        /// <summary>
        /// Gets and sets the text used for searching.
        /// Please note that when this property is set a search will be executed
        /// </summary>
        public string SearchText
        {
            get { return searchText; }
            set
            {
                searchText = value;

                SearchReportType searchReportType;
                Enum.TryParse<SearchReportType>(GetValue(SearchReportTypeProperty).ToString(), out searchReportType);
                String MainFilterParamGUID = GetValue(MainFilterParamGUIDProperty).ToString();

                ReportsView.Filter = delegate(object item)
                {
                    bool bCont = true;
                    switch (searchReportType)
                    {
                        case SearchReportType.SearchByCompany:
                            {
                                String val = item.GetType().GetProperty("CompanyId").GetValue(item, null).ToString();
                                bCont = String.IsNullOrEmpty(val) ? true : val.Equals(MainFilterParamGUID);
                                break;
                            }
                        case SearchReportType.SearchByService:
                            {
                                String val = item.GetType().GetProperty("Lift_ServiceId").GetValue(item, null).ToString();
                                bCont = String.IsNullOrEmpty(val) ? true : val.Equals(MainFilterParamGUID.ToString());
                                break;
                            }
                        case SearchReportType.CustomSearch:
                            bCont = true;
                            break;
                        default:
                            break;
                    }
                    //if (bCont)
                    //{
                    //    if (String.IsNullOrEmpty(value))
                    //        return true;

                    //    String val = item.GetType().GetProperty((cbFindBy.SelectedValue as SearchObj).FieldName).GetValue(item, null).ToString();
                    //    return String.IsNullOrEmpty(val) ? true : val.Contains(value);
                    //}
                    return false;
                };

                OnPropertyChanged("TotalReports");
            }
        }

        #endregion


        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion

        private void btnClearFilter_Click(object sender, RoutedEventArgs e)
        {
            SearchText = String.Empty;
            OnPropertyChanged("SearchText");
        }

        private void dgReports_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (OnDataGridSelectedData != null)
            {
                OnDataGridSelectedData(sender, new DataGridSelectedArgs() { DataList = dgItemsEx.SelectedItems });
            }
        }

        private void dgItems_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            OnPropertyChanged("CurrentReportIndex");
        }

    }

}
